/**
 * @param {string} s
 * @param {number=} hash
 * @returns {number}
 */
function djb2(s, hash = 5381) {
  let i = s.length;

  while (i) {
    hash = (hash * 33) ^ s.charCodeAt(--i);
  }

  return hash;
}

/**
 * @param {string} input
 * @returns {string}
 */
function fnv1(input) {
  // FNV-1 32-bit constants
  const FNV_PRIME = 0x01000193; // 16777619
  const OFFSET_BASIS = 0x811c9dc5; // 2166136261

  let hash = OFFSET_BASIS;

  for (let i = 0; i < input.length; i++) {
    // Multiply by FNV prime, modulo 2^32
    hash = (hash * FNV_PRIME) >>> 0; // To positive
    // XOR the lower 8 bits of the hash with the current byte of the input
    hash ^= input.charCodeAt(i);
  }

  return hash.toString(16);
}

export { djb2, fnv1 };
